/*
 * @Author: hongbin
 * @Date: 2023-04-14 10:47:44
 * @LastEditors: hongbin
 * @LastEditTime: 2023-04-14 21:39:44
 * @Description:扫射
 */
import Layout from "@/components/Three/Layout";
import { ThreeHelper } from "@/ThreeHelper";
import { FC } from "react";
import * as THREE from "three";

import vertexShader from "../../components/strafe/vt.glsl";
import fragmentShader from "../../components/strafe/gm.glsl";
import { GradualBoxes } from "@/components/gradual/GradualBoxes";

interface IProps {}

const Strafe: FC<IProps> = () => {
    return <Layout title={"shader 扫射"} init={init} desc={"shader 扫射"} />;
};

export default Strafe;

function init(helper: ThreeHelper) {
    helper.addStats();
    // helper.addAxis();
    helper.camera.position.set(0, 100, 3);
    helper.frameByFrame();
    helper.addGUI();
    helper.initLights();
    // helper.transparentBackGround();
    // helper.renderer.domElement.style.background =
    //     "linear-gradient(45deg, #036eef, #f00505)";

    const shader = new THREE.ShaderMaterial({
        vertexShader,
        fragmentShader,
        uniforms: {
            color1: { value: new THREE.Color("#f00") },
            color2: { value: new THREE.Color("#7204f8") },
            time: { value: 0 },
            range: { value: 0 },
        },
        transparent: true,
        side: THREE.DoubleSide,
    });

    const geo = new THREE.PlaneGeometry(100, 100);
    const plane = new THREE.Mesh(
        geo,
        // new THREE.MeshStandardMaterial({ side: THREE.DoubleSide })
        shader
    );
    plane.position.y += 0.3;
    plane.rotateX(Math.PI / -2);

    helper.add(plane);

    const gradualBoxes = new GradualBoxes(1000, 100);

    helper.add(gradualBoxes.group);

    const floor = new THREE.Mesh(
        new THREE.BoxGeometry(80, 0.1, 80),
        new THREE.MeshStandardMaterial({
            color: "#030303",
        })
    );

    helper.add(floor);
    const forceColor = new THREE.Color("#f40cf0");

    gradualBoxes.update((box) => {
        box.material.uniforms.forceColor = { value: forceColor };
    });

    helper.animation(() => {
        // const time = helper.clock.getElapsedTime();

        // shader.uniforms.range.value = Math.abs(Math.sin(time));
        shader.uniforms.range.value += 0.005;
        shader.uniforms.range.value %= 1;

        const range = shader.uniforms.range.value;

        const far = range * 33;
        const near = (range - 0.2) * 33;
        const decay = range > 0.8 ? (range - 0.8) * 4.9 : 0;
        shader.uniforms.decay = { value: decay };
        const boxDecay = range > 0.8 ? 1 - (range - 0.8) * 5 : 1;

        gradualBoxes.update((box) => {
            box.material.uniforms.decay = {
                value: boxDecay,
            };
            const distance = box.position.distanceTo(plane.position);
            if (distance > near && distance < far) {
                const p = (distance - near) / (far - near);
                box.material.uniforms.isForceColor = { value: p };
            } else {
                box.material.uniforms.isForceColor = { value: -1 };
            }
        });
    });
}
